package com.sz.admin.system.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.sz.admin.system.mapper.SysFileMonitorMapper;
import com.sz.admin.system.pojo.dto.filemonitor.SysFileMonitorCreateDTO;
import com.sz.admin.system.pojo.dto.filemonitor.SysFileMonitorListDTO;
import com.sz.admin.system.pojo.dto.filemonitor.SysFileMonitorUpdateDTO;
import com.sz.admin.system.pojo.po.SysFileMonitor;
import com.sz.admin.system.pojo.vo.filemonitor.SysFileMonitorVO;
import com.sz.admin.system.service.SysFileMonitorService;
import com.sz.core.common.entity.PageResult;
import com.sz.core.common.entity.SelectIdsDTO;
import com.sz.core.common.enums.CommonResponseEnum;
import com.sz.core.util.BeanCopyUtils;
import com.sz.core.util.PageUtils;
import com.sz.core.util.Utils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import cn.dev33.satoken.stp.StpUtil;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 文件监控服务实现类
 *
 * @author sz-admin
 * @since 2025-01-13
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysFileMonitorServiceImpl extends ServiceImpl<SysFileMonitorMapper, SysFileMonitor> implements SysFileMonitorService {

    @Override
    public void create(SysFileMonitorCreateDTO dto) {
        SysFileMonitor sysFileMonitor = BeanCopyUtils.copy(dto, SysFileMonitor.class);
        
        // 检查路径是否已存在
        QueryWrapper wrapper = QueryWrapper.create()
                .eq(SysFileMonitor::getMonitorPath, dto.getMonitorPath())
                .eq(SysFileMonitor::getDelFlag, "F");
        CommonResponseEnum.EXISTS.message("监控路径已存在").assertTrue(count(wrapper) > 0);
        
        // 设置审计字段
        sysFileMonitor.setCreateTime(LocalDateTime.now());
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            sysFileMonitor.setCreateId(userId);
        } catch (Exception e) {
            // 如果获取登录用户失败，则不设置创建人
            log.debug("获取当前用户信息失败，跳过设置创建人: {}", e.getMessage());
        }
        sysFileMonitor.setDelFlag("F");
        
        save(sysFileMonitor);
    }

    @Override
    public void update(SysFileMonitorUpdateDTO dto) {
        SysFileMonitor sysFileMonitor = BeanCopyUtils.copy(dto, SysFileMonitor.class);
        QueryWrapper wrapper;
        
        // id有效性校验
        wrapper = QueryWrapper.create().eq(SysFileMonitor::getId, dto.getId());
        CommonResponseEnum.INVALID_ID.assertTrue(count(wrapper) <= 0);

        // 检查路径是否已存在（排除当前记录）
        wrapper = QueryWrapper.create()
                .eq(SysFileMonitor::getMonitorPath, dto.getMonitorPath())
                .ne(SysFileMonitor::getId, dto.getId())
                .eq(SysFileMonitor::getDelFlag, "F");
        CommonResponseEnum.EXISTS.message("监控路径已存在").assertTrue(count(wrapper) > 0);

        // 设置审计字段
        sysFileMonitor.setUpdateTime(LocalDateTime.now());
        try {
            Long userId = StpUtil.getLoginIdAsLong();
            sysFileMonitor.setUpdateId(userId);
        } catch (Exception e) {
            // 如果获取登录用户失败，则不设置更新人
            log.debug("获取当前用户信息失败，跳过设置更新人: {}", e.getMessage());
        }

        saveOrUpdate(sysFileMonitor);
    }

    @Override
    public PageResult<SysFileMonitorVO> page(SysFileMonitorListDTO dto) {
        Page<SysFileMonitorVO> page = pageAs(PageUtils.getPage(dto), buildQueryWrapper(dto), SysFileMonitorVO.class);
        return PageUtils.getPageResult(page);
    }

    @Override
    public List<SysFileMonitorVO> list(SysFileMonitorListDTO dto) {
        return listAs(buildQueryWrapper(dto), SysFileMonitorVO.class);
    }

    @Override
    public void remove(SelectIdsDTO dto) {
        CommonResponseEnum.INVALID_ID.assertTrue(dto.getIds().isEmpty());
        removeByIds(dto.getIds());
    }

    @Override
    public SysFileMonitorVO detail(Object id) {
        SysFileMonitor sysFileMonitor = getById((Serializable) id);
        CommonResponseEnum.INVALID_ID.assertNull(sysFileMonitor);
        return BeanCopyUtils.copy(sysFileMonitor, SysFileMonitorVO.class);
    }

    @Override
    public void enableMonitor(Long id) {
        SysFileMonitor monitor = getById(id);
        CommonResponseEnum.INVALID_ID.assertNull(monitor);
        monitor.setStatus("1");
        updateById(monitor);
    }

    @Override
    public void disableMonitor(Long id) {
        SysFileMonitor monitor = getById(id);
        CommonResponseEnum.INVALID_ID.assertNull(monitor);
        monitor.setStatus("0");
        updateById(monitor);
    }

    @Override
    public List<SysFileMonitor> getEnabledMonitors() {
        QueryWrapper wrapper = QueryWrapper.create()
                .eq(SysFileMonitor::getStatus, "1")
                .eq(SysFileMonitor::getDelFlag, "F");
        return list(wrapper);
    }

    private static QueryWrapper buildQueryWrapper(SysFileMonitorListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(SysFileMonitor.class);
        
        if (Utils.isNotNull(dto.getMonitorPath())) {
            wrapper.like(SysFileMonitor::getMonitorPath, dto.getMonitorPath());
        }
        if (Utils.isNotNull(dto.getStatus())) {
            wrapper.eq(SysFileMonitor::getStatus, dto.getStatus());
        }
        if (Utils.isNotNull(dto.getStorageDir())) {
            wrapper.like(SysFileMonitor::getStorageDir, dto.getStorageDir());
        }
        
        wrapper.orderBy(SysFileMonitor::getCreateTime, false);
        return wrapper;
    }

}